/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2023-09-29     FuLei       the first version
 */
//#ifndef APPLICATIONS_TASK_C_
//#define APPLICATIONS_TASK_C_

#include <task.h>
#include <Motor.h>
#include <OledDisplayCode.h>
#include <key_check.h>
#include <board.h>
/* 信号量  事件集 定义 */
//struct rt_event PM_Event;
//struct rt_semaphore sem_uart6;


//-------------创建线程相关---------------------
/* part1 线程句柄定义 */
struct rt_thread  handle_thead_01_heart;          // 线程01句柄
struct rt_thread  handle_thead_02_print;          // 线程02句柄
struct rt_thread  handle_thead_03_DAQ;            // 线程03句柄
struct rt_thread  handle_thead_04_Ctrl;           // 线程04句柄

/* part2 线程入口函数声明 */
void Thread_01_heartbeat(void *argu);
void Thread_02_print(void *argu);
void Thread_03_DAQ(void *argu);
void Thread_04_Ctrl(void *argu);

/* part3 静态分配线程内存 */
rt_uint8_t stack_thead_01_heart[1024];
rt_uint8_t stack_thead_02_print[1024];
rt_uint8_t stack_thead_03_DAQ[2048];
rt_uint8_t stack_thead_04_Ctrl[3072];

//* part4 线程优先级定义*/
#define THREAD_01_HEARTBEAT_PRIOR     23
#define THREAD_02_PRINT_PRIOR         20
#define THREAD_03_DAQ_PRIOR           20
#define THREAD_04_CTRL_PRIOR          21


extern KeyDataFrm KeyData;


/**********************函数描述*********************
* 创建人:   傅雷
* 创建时间: 2023.10.01
* 功能描述:  线程创建
* 入口参数: void
* 函数返回: void
******************************************************/
void thread_create(void)
{
    // ------------线程1    呼吸线程 静态创建------------------
    rt_thread_init(  &handle_thead_01_heart,              // part1 线程句柄
                     "Heartbeat_thread",                       // 线程名称
                     Thread_01_heartbeat,                 // part2 线程入口函数
                     RT_NULL,                             // 线程入口函数参数
                     &stack_thead_01_heart[0],            // part3 线程栈起始地址
                     sizeof(stack_thead_01_heart),        // part3 线程栈大小
                     THREAD_01_HEARTBEAT_PRIOR,           // part4 线程的优先级
                     5);                                 // 线程时间片

//    rt_thread_startup( &handle_thead_01_heart );          // 启动线程01
    // --------- ---------END OF 线程1------------------ ------- -------

    // -- --------线程2    PRINT线程 静态创建 ------------------
    rt_thread_init(  &handle_thead_02_print,              // part1 线程句柄
                     "PRINT_thread",                  // 线程名称
                     Thread_02_print,                     // part2 线程入口函数
                     RT_NULL,                             // 线程入口函数参数
                     &stack_thead_02_print[0],            // part3 线程栈起始地址
                     sizeof(stack_thead_02_print),        // part3 线程栈大小
                     THREAD_02_PRINT_PRIOR,               // part4 线程的优先级
                     5);                                 // 线程时间片

    rt_thread_startup( &handle_thead_02_print );          // 启动线程02
    // ------------------END OF 线程2------------------------------

    // -------------线程3    DAQ线程 静态创建----------------------
    rt_thread_init(  &handle_thead_03_DAQ,              // part1 线程句柄
                     "DAQ_thread",                     // 线程名称
                     Thread_03_DAQ,                     // part2 线程入口函数
                     RT_NULL,                             // 线程入口函数参数
                     &stack_thead_03_DAQ[0],            // part3 线程栈起始地址
                     sizeof(stack_thead_03_DAQ),        // part3 线程栈大小
                     THREAD_03_DAQ_PRIOR,               // part4 线程的优先级
                     5);                                 // 线程时间片

    rt_thread_startup( &handle_thead_03_DAQ );          // 启动线程03
    // ------------------END OF 线程3------------------------------

    // ---线程4    Control线程 静态创建
    rt_thread_init(  &handle_thead_04_Ctrl,              // part1 线程句柄
                     "Ctrl_thread",                     // 线程名称
                     Thread_04_Ctrl,                    // part2 线程入口函数
                     RT_NULL,                             // 线程入口函数参数
                     &stack_thead_04_Ctrl[0],            // part3 线程栈起始地址
                     sizeof(stack_thead_04_Ctrl),        // part3 线程栈大小
                     THREAD_04_CTRL_PRIOR,               // part4 线程的优先级
                     5);                                 // 线程时间片

    rt_thread_startup( &handle_thead_04_Ctrl );          // 启动线程04

}

//=============
/**********************函数描述*********************
* 创建人:   傅雷
* 创建时间: 2023.10.01
* 功能描述:  线程01 心跳
* 入口参数: void
* 函数返回: void
******************************************************/
void Thread_01_heartbeat(void *argu)
{
    //暂时关闭线程
}

/**********************函数描述*********************
* 创建人:   傅雷
* 创建时间: 2023.10.01
* 功能描述:  线程02  急停线程
* 入口参数: void
* 函数返回: void
******************************************************/
rt_uint8_t Thread2_Flag = 1;
void Thread_02_print(void *argu)
{
    //线程2第一次开启时，先挂起
    if (Thread2_Flag) {
        Thread2_Flag--;
        rt_thread_suspend(&handle_thead_02_print);
        rt_schedule();
    }
    uint8_t count = 0;

    //急停后开启
    while(1)
    {
        //检测急停按键
        EmergencyStop_Check();

        count ++;
        rt_thread_mdelay(50);
        //led闪烁
        if (count == 20) {
            count = 0;
            LED_Flash();
        }
    }

}

/**********************函数描述*********************
* 创建人:   傅雷
* 创建时间: 2023.10.01
* 功能描述:  线程03  解析力、按键
* 入口参数: void
* 函数返回: void
******************************************************/

LoadDataFrm pLoad;
LoadDataFrm pLoad1;
void Thread_03_DAQ(void *argu)
{
    //小量程 标定参数
    pLoad.para_filter = 15;
    pLoad.X_adc[1] = 6225910;
    pLoad.X_adc[0] = 5970610;
    pLoad.Y_force[1] = 1;
    pLoad.Y_force[0] = 0;
    //大量程 标定参数
    pLoad1.para_filter = 15;
    pLoad1.X_adc[1] = 8500000;
    pLoad1.X_adc[0] = 8383531;
    pLoad1.Y_force[1] = 70;
    pLoad1.Y_force[0] = 0;

    while(1)
    {
        //按键检测
        KEY_CHECK();

        //光电传感器状态检测
        PhotoElectricity_Check();
//        rt_kprintf("%d\n",rt_pin_read(GET_PIN(C,15)));
        //检测转速
        SpeedCheck();

        //-------切换通道1 2（大量程）-------------
//        rt_thread_mdelay(10);
        AD7190_ConfigReg_Switch();
        rt_thread_mdelay(10);

        //获取AD值
        pLoad1.cur_ad7190_adc = AD7190_DataReg_RD();
        //处理ad值
        LoadData_Sensor(&pLoad1);
//        rt_kprintf("adc:%d force:%.3f delta:%.3f\n",pLoad1.cur_ad7190_adc, pLoad1.cur_realforce, pLoad1.delta_force);

        //-------切换通道3 4 (小量程)-------------
        rt_thread_mdelay(5);
        AD7190_ConfigReg_Set();
        rt_thread_mdelay(10);

        //获取AD值
        pLoad.cur_ad7190_adc = AD7190_DataReg_RD();
        //处理ad值
        LoadData_Sensor(&pLoad);
//        rt_kprintf("adc:%d force:%.3f delta:%.3f\n",pLoad.cur_ad7190_adc, pLoad.cur_realforce, pLoad.delta_force);

        //手握模式检测
        if (KeyFlag.Key_switch_f == 0)
        {
            MotionDetection(pLoad, StartData.period, StartData.pulse); //检测电机启动
        }
    }
}

/**********************函数描述*********************
* 创建人:   傅雷
* 创建时间: 2023.10.01
* 功能描述:  线程04  oled显示
* 入口参数: void
* 函数返回: void
******************************************************/
char var_buff[20];              //用来存ASCII码
char var_buff2[20];              //用来存ASCII码
char var_buff3[20];              //用来存ASCII码
void Thread_04_Ctrl(void *argu)
{
    u8g2_SetFont(&u8g2, u8g2_font_wqy12_t_gb2312a);
    while(1)
    {
        OledDisplay();
    }
}

//----------------------要显示的内容----------------------------
void OledDisplay(void)
{
    //------------------中文显示-------------------------
    u8g2_DrawUTF8(&u8g2, 45, 60, "重量：");
    u8g2_DrawUTF8(&u8g2, 115, 60, "kg");

    //按键切换 显示
    //------------------悬浮、手握--------------------------
    if (KeyFlag.Key_switch_f == 0) {
        u8g2_DrawUTF8(&u8g2, 2, 20, "手握模式");  // 将 "手握模式" 输出至 (x, y) 坐标位置
    }else {
        u8g2_DrawUTF8(&u8g2, 2, 20, "悬浮模式");  // 将 "手握模式" 输出至 (x, y) 坐标位置
    }
    //------------------低、中、高 速--------------------------
    if (KeyFlag.key_up_data == 0) {
        u8g2_DrawUTF8(&u8g2, 80, 20, "低速模式");  // 将 "低速模式" 输出至 (x, y) 坐标位置
    }else if (KeyFlag.key_up_data == 1) {
        u8g2_DrawUTF8(&u8g2, 80, 20, "中速模式");  // 将 "低速模式" 输出至 (x, y) 坐标位置
    }else if (KeyFlag.key_up_data == 2){
        u8g2_DrawUTF8(&u8g2, 80, 20, "高速模式");  // 将 "低速模式" 输出至 (x, y) 坐标位置
    }else {
        u8g2_DrawUTF8(&u8g2, 80, 20, "自动模式");  // 将 "低速模式" 输出至 (x, y) 坐标位置
    }
    //------------------设置灵敏度参数--------------------------
    if (KeyFlag.Key_set_f == 1) {
        sprintf(var_buff2, "%.2f", Sensitivity);  //传递变量（十进制（占四格））
        u8g2_DrawStr(&u8g2, 5, 60, var_buff2); //加载到缓存
    }
    //------------------急停显示--------------------------
    if (!rt_pin_read(GET_PIN(C,14))) {
        u8g2_DrawUTF8(&u8g2, 52, 40, "急停!");
    }
    //---------------------重量变化-----------------------
    sprintf(var_buff, "%.3f", pLoad.cur_realforce-pLoad1.cur_realforce);  //传递变量（十进制（占四格））
    u8g2_DrawStr(&u8g2, 72, 60, var_buff); //加载到缓存

    u8g2_SendBuffer(&u8g2);              //发送到屏幕
    u8g2_ClearBuffer(&u8g2);

    rt_thread_mdelay(2);
}

//电机转速切换
void SpeedCheck(void)
{
    if (KeyFlag.key_up_data == 0) {
        //电机启动参数 低速
        StartData.period = 1000000/4;
        StartData.pulse = 1000000/8;
    }else if (KeyFlag.key_up_data == 1) {
        //电机启动参数 中速
        StartData.period = 700000/4;
        StartData.pulse = 700000/8;
    }else if (KeyFlag.key_up_data == 2)
    {
        //电机启动参数 高速
        StartData.period = 300000/4;
        StartData.pulse = 300000/8;
    }else {
        //电机启动参数 低速
        StartData.period = 1000000/4;
        StartData.pulse = 1000000/8;
    }
}
























//#endif /* APPLICATIONS_TASK_C_ */
